package com.example.modulepicselector.view.widget;


import android.content.Context;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;


import java.util.Timer;
import java.util.TimerTask;


public class ScaleImageView extends AppCompatImageView implements View.OnTouchListener {
    public static final String TAG = "ScaleImageView";
    public static final float SCALE_MAX = 5.0f; //最大的缩放比例
    private static final float SCALE_MIN = 1.0f;
    private double oldDist = 0;
    private float downX1 = 0;
    private float downX2 = 0;
    private float downY1 = 0;
    private float downY2 = 0;
    private float downX = 0;
    private float downY = 0;
    private VelocityTracker mVelocityTracker;
    private Timer mTimer;
    private MyTimeTask mMyTimeTask;
    private boolean mIsPassTwoPointer =false;
    private final Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == 1) {
                setSelfPivot(msg.arg1, msg.arg2);
            }
        }
    };


    private final int mTouchSlop;


    private boolean isCanDrag;

    public ScaleImageView(Context context) {
        this(context, null);
    }

    public ScaleImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setOnTouchListener(this);


        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int pointerCount = event.getPointerCount();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mIsPassTwoPointer =false;
                if (pointerCount == 1) {
                    downX = event.getRawX();
                    downY = event.getRawY();
                    mVelocityTracker = VelocityTracker.obtain();
                    if (mVelocityTracker != null) {
                        //将当前事件添加到检测器中
                        mVelocityTracker.addMovement(event);
                        //当手指再次点击到图片时候，停止图片的滑动惯性

                    }

                }
                break;
            case MotionEvent.ACTION_UP:
                if (pointerCount == 2) {
                    downX1 = 0;
                    downY1 = 0;
                    downX2 = 0;
                    downY2 = 0;
                }
                if (isCanDrag) {

                    if (mVelocityTracker != null) {
                        mVelocityTracker.addMovement(event);
                        mVelocityTracker.computeCurrentVelocity(1000);
                        final float vX = mVelocityTracker.getXVelocity();
                        final float vY = mVelocityTracker.getYVelocity();
                        startTimer((int) vX / 2, (int) vY / 2);


                    }
                }


                break;
            case MotionEvent.ACTION_MOVE:
                if (pointerCount == 2) {
                    mIsPassTwoPointer = true;
                    float x1 = event.getX(0);
                    float x2 = event.getX(1);
                    float y1 = event.getY(0);
                    float y2 = event.getY(1);

                    double changeX1 = x1 - downX1;
                    double changeX2 = x2 - downX2;
                    double changeY1 = y1 - downY1;
                    double changeY2 = y2 - downY2;

                    if (getScaleX() > 1) { //滑动
                        float lessX = (float) ((changeX1) / 2 + (changeX2) / 2);
                        float lessY = (float) ((changeY1) / 2 + (changeY2) / 2);
                        setSelfPivot(-lessX, -lessY);

                    }


                    //缩放处理
                    double moveDist = spacing(event);
                    double space = moveDist - oldDist;
                    float scale = (float) (getScaleX() + space / v.getWidth());
                    if (scale < SCALE_MIN) {
                        setScale(SCALE_MIN);
                    } else setScale(Math.min(scale, SCALE_MAX));

                    break;
                } else if (pointerCount == 1) {
                    if (!mIsPassTwoPointer) {
                        float x;
                        x = event.getRawX();
                        float y = event.getRawY();
                        float changeX = x - downX;
                        float changeY = y - downY;

                        if (isMoveAction(changeX, changeY)) {
                            isCanDrag = true;
                        }

                        if (changeX > 10 || changeX < -10 || changeY > 10 || changeY < -10) {
                            setSelfPivot(-changeX, -changeY);
                            downX = event.getRawX();
                            downY = event.getRawY();
                        }
                        if (getDrawable() != null) {
                            if (mVelocityTracker != null) {
                                mVelocityTracker.addMovement(event);
                            }
                        }

                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                if (pointerCount == 2) {

                    downX1 = event.getX(0);
                    downX2 = event.getX(1);
                    downY1 = event.getY(0);
                    downY2 = event.getY(1);
                    oldDist = spacing(event); //两点按下时的距离
                }

                break;
            case MotionEvent.ACTION_POINTER_UP:
                if (pointerCount == 1){
                    mIsPassTwoPointer = true;
                }

                Log.d(TAG, "ACTION_POINTER_UP");
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * 触摸使用的移动事件
     *
     * @param lessX lessX
     * @param lessY lessY
     */
    private void setSelfPivot(float lessX, float lessY) {
        float setPivotX;
        float setPivotY;
        setPivotX = getPivotX() + lessX;
        setPivotY = getPivotY() + lessY;
        if (setPivotX < 0 && setPivotY < 0) {
            setPivotX = 0;
            setPivotY = 0;
        } else if (setPivotX > 0 && setPivotY < 0) {
            setPivotY = 0;
            if (setPivotX > getWidth()) {
                setPivotX = getWidth();
                getParent().requestDisallowInterceptTouchEvent(false);
            }
        } else if (setPivotX < 0 && setPivotY > 0) {
            setPivotX = 0;
            if (setPivotY > getHeight()) {
                setPivotY = getHeight();
            }
        } else {
            if (setPivotX > getWidth()) {
                setPivotX = getWidth();
                getParent().requestDisallowInterceptTouchEvent(false);
            }
            if (setPivotY > getHeight()) {
                setPivotY = getHeight();
            }
        }
        setPivot(setPivotX, setPivotY);
    }

    /**
     * 计算两个点的距离
     *
     * @param event  触摸的事件
     * @return    距离
     */
    private double spacing(MotionEvent event) {
        if (event.getPointerCount() == 2) {
            float x = 0;
            float y = 0;
            try {
                x = event.getX(0) - event.getX(1);
                y = event.getY(0) - event.getY(1);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }


            return Math.sqrt(x * x + y * y);
        } else {
            return 0;
        }
    }

    /**
     * 平移画面，当画面的宽或高大于屏幕宽高时，调用此方法进行平移
     *
     * @param x x
     * @param y y
     */
    public void setPivot(float x, float y) {
        setPivotX(x);
        setPivotY(y);
    }


    /**
     * 设置放大缩小
     *
     * @param scale  屏幕的倍率
     */
    public void setScale(float scale) {
        setScaleX(scale);
        setScaleY(scale);
    }


    /**
     * 判断是否是移动的操作
     */
    private boolean isMoveAction(float dx, float dy) {
        //勾股定理，判断斜边是否大于可滑动的一个临界值
        return Math.sqrt(dx * dx + dy * dy) > mTouchSlop;
    }

    public void setViewPager() {
    }

    private class MyTimeTask extends TimerTask {

        private int vX1;
        private int vY1;

        public MyTimeTask(int vX1, int vY1) {
            this.vX1 = vX1;
            this.vY1 = vY1;
        }

        @Override
        public void run() {
            this.vX1 = (int) (vX1 * (0.95));
            this.vY1 = (int) (vY1 * (0.95));
            Message message = handler.obtainMessage();
            message.arg1 = vX1;
            message.arg2 = vY1;
            message.what = 1;
            handler.sendMessage(message);
            if (vX1 < 1 && vY1 < 1) {
                stopTimer();
            }


        }
    }

    private void stopTimer() {
        if (mTimer != null) {
            mTimer.cancel();
        }
        mTimer = null;
        if (mMyTimeTask != null) {
            mMyTimeTask.cancel();
        }
        mMyTimeTask = null;
    }

    private void startTimer(int vx, int vy) {
        mTimer = new Timer(true);
        mMyTimeTask = new MyTimeTask(vx, vy);
        mTimer.schedule(mMyTimeTask, 0, 16);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                if (event.getPointerCount() == 1) {
                    if (getScaleY() <= 1 || getScaleX() <= 1) {
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }


                } else {
                    getParent().requestDisallowInterceptTouchEvent(true);
                }

                break;
            default:
                break;
        }


        return super.dispatchTouchEvent(event);
    }


}
